// StateMachine.cs
using Godot;
using System.Collections.Generic;


/// <summary>
/// 状态的接口
/// </summary>
public interface IState
{
    void Enter();
    void Exit();
    void Update(double delta);
    void PhysicsUpdate(double delta);
    void HandleInput(InputEvent @event);
}

/// <summary>
/// 状态机
/// </summary>
[GlobalClass]
public partial class StateMachine : Node
{
    private Dictionary<StringName, IState> _states = new Dictionary<StringName, IState>();
    private IState _currentState;
    
    [Signal]
    public delegate void StateChangedEventHandler(StringName stateName);
    
    [Export]
    public StringName InitialState { get; set; }
    
    public StringName CurrentStateName { get; private set; }
    
    public override void _Ready()
    {
        // 获取所有子节点作为状态
        foreach (Node child in GetChildren())
        {
            if (child is IState state)
            {
                _states[child.Name] = state;
            }
        }
        
        // 设置初始状态
        if (_states.ContainsKey(InitialState))
        {
            ChangeState(InitialState);
        }
        else
        {
            GD.PrintErr($"Initial state '{InitialState}' not found!");
        }
    }
    
    public override void _Process(double delta)
    {
        _currentState?.Update(delta);
    }
    
    public override void _PhysicsProcess(double delta)
    {
        _currentState?.PhysicsUpdate(delta);
    }
    
    public override void _Input(InputEvent @event)
    {
        _currentState?.HandleInput(@event);
    }
    
    public bool ChangeState(StringName newStateName)
    {
        if (_states.ContainsKey(newStateName) && newStateName != CurrentStateName)
        {
            _currentState?.Exit();
            _currentState = _states[newStateName];
            CurrentStateName = newStateName;
            _currentState.Enter();
            return true;
        }
        return false;
    }
    
    public bool IsCurrentState(StringName stateName)
    {
        return CurrentStateName == stateName;
    }
}